﻿#include "FriendDialog.h"
#include "../../MirGraphics/MLibrary.h"
#include "../../MirSounds/SoundManager.h"
#include "../../../Shared/Language.h"
#include "../GameScene.h"
#include "../../MirNetwork/Network.h"
#include "../../../Shared/ClientPackets.h"
#include "../../Settings.h"

using namespace Client::MirControls;
using namespace Client::MirGraphics;
using namespace Client::MirNetwork;
using namespace Client::MirSounds;
namespace C = ClientPackets;

namespace Client::MirScenes::Dialogs
{

    FriendDialog::FriendDialog()
    {
        setIndex(199);
        setLibrary(Libraries::Title);
        setMovable(true);
        setSort(true);
        setLocation(getCenter());

        TitleLabel = new MirImageControl();
        TitleLabel->setIndex(6);
        TitleLabel->setLibrary(Libraries::Title);
        Point tempVar(18, 8);
        TitleLabel->setLocation(&tempVar);
        TitleLabel->setParent(this);

        FriendLabel = new MirImageControl();
        FriendLabel->setIndex(163);
        FriendLabel->setLibrary(Libraries::Title);
        Point tempVar2(10, 34);
        FriendLabel->setLocation(&tempVar2);
        FriendLabel->setParent(this);
        FriendLabel->setSound(SoundList::ButtonA);
        FriendLabel->Click += [&] (o, e)
        {
            _tempBlockedTab = false;
            UpdateDisplay();
        };

        BlacklistLabel = new MirImageControl();
        BlacklistLabel->setIndex(167);
        BlacklistLabel->setLibrary(Libraries::Title);
        Point tempVar3(128, 34);
        BlacklistLabel->setLocation(&tempVar3);
        BlacklistLabel->setParent(this);
        BlacklistLabel->setSound(SoundList::ButtonA);
        BlacklistLabel->Click += [&] (o, e)
        {
            _tempBlockedTab = true;
            UpdateDisplay();
        };

        PageNumberLabel = new MirLabel();
        PageNumberLabel->setText("");
        PageNumberLabel->setParent(this);
        Size tempVar4(83, 17);
        PageNumberLabel->setSize(&tempVar4);
        Point tempVar5(87, 216);
        PageNumberLabel->setLocation(&tempVar5);
        PageNumberLabel->setDrawFormat(TextFormatFlags::HorizontalCenter | TextFormatFlags::VerticalCenter);

        #pragma region Buttons

        PreviousButton = new MirButton();
        PreviousButton->setIndex(240);
        PreviousButton->setHoverIndex(241);
        PreviousButton->setPressedIndex(242);
        PreviousButton->setLibrary(Libraries::Prguse2);
        PreviousButton->setParent(this);
        Size tempVar6(16, 16);
        PreviousButton->setSize(&tempVar6);
        Point tempVar7(70, 218);
        PreviousButton->setLocation(&tempVar7);
        PreviousButton->setSound(SoundList::ButtonA);
        PreviousButton->Click += [&] (o, e)
        {
            Page--;
            if (Page < 0)
            {
                Page = 0;
            }
            StartIndex = Rows.size() * Page;
            Update();
        };

        NextButton = new MirButton();
        NextButton->setIndex(243);
        NextButton->setHoverIndex(244);
        NextButton->setPressedIndex(245);
        NextButton->setLibrary(Libraries::Prguse2);
        NextButton->setParent(this);
        Size tempVar8(16, 16);
        NextButton->setSize(&tempVar8);
        Point tempVar9(171, 218);
        NextButton->setLocation(&tempVar9);
        NextButton->setSound(SoundList::ButtonA);
        NextButton->Click += [&] (o, e)
        {
            Page++;
            if (Page > Friends.size()() / Rows.size())
            {
                Page = Friends.size()() / Rows.size();
            }
            StartIndex = Rows.size() * Page;
    
            Update();
        };

        CloseButton = new MirButton();
        CloseButton->setHoverIndex(361);
        CloseButton->setIndex(360);
        Point tempVar10(237, 3);
        CloseButton->setLocation(&tempVar10);
        CloseButton->setLibrary(Libraries::Prguse2);
        CloseButton->setParent(this);
        CloseButton->setPressedIndex(362);
        CloseButton->setSound(SoundList::ButtonA);
        CloseButton->Click += [&] (o, e)
        {
            Hide();
        };

        AddButton = new MirButton();
        AddButton->setIndex(554);
        AddButton->setHoverIndex(555);
        AddButton->setPressedIndex(556);
        AddButton->setLibrary(Libraries::Prguse);
        Point tempVar11(60, 241);
        AddButton->setLocation(&tempVar11);
        AddButton->setParent(this);
        AddButton->setSound(SoundList::ButtonA);
        AddButton->setHint(GameLanguage::AddFriend);
        AddButton->Click += [&] (o, e)
        {
            std::string message = GameLanguage::FriendEnterAddName;
            if (_blockedTab)
            {
                message = GameLanguage::FriendEnterBlockName;
            }
    
            MirInputBox *inputBox = new MirInputBox(message);
    
            inputBox->OKButton->Click += [&] (o1, e1)
            {
                    C::AddFriend *tempVar12 = new C::AddFriend();
                    tempVar12->Name = inputBox->InputTextBox->getText();
                    tempVar12->Blocked = _blockedTab;
                    Network::Enqueue(tempVar12);
                    inputBox->Dispose();

//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar12' statement was not added since tempVar12 was passed to a method or constructor. Handle memory management manually.
            };
    
            inputBox->Show();

            delete inputBox;
        };

        RemoveButton = new MirButton();
        RemoveButton->setIndex(557);
        RemoveButton->setHoverIndex(558);
        RemoveButton->setPressedIndex(559);
        RemoveButton->setLibrary(Libraries::Prguse);
        Point tempVar13(88, 241);
        RemoveButton->setLocation(&tempVar13);
        RemoveButton->setParent(this);
        RemoveButton->setSound(SoundList::ButtonA);
        RemoveButton->setHint(GameLanguage::RemoveFriend);
        RemoveButton->Click += [&] (o, e)
        {
            if (SelectedFriend == nullptr)
            {
                return;
            }
    
            MirMessageBox *messageBox = new MirMessageBox(StringHelper::formatSimple("Are you sure you wish to remove '{0}'?", SelectedFriend->Name), MirMessageBoxButtons::YesNo);
    
            messageBox->YesButton->Click += [&] (o1, e1)
            {
                    C::RemoveFriend *tempVar14 = new C::RemoveFriend();
                    tempVar14->CharacterIndex = SelectedFriend->Index;
                    Network::Enqueue(tempVar14);
                    messageBox->Dispose();

//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar14' statement was not added since tempVar14 was passed to a method or constructor. Handle memory management manually.
            };
    
            messageBox->Show();

            delete messageBox;
        };

        MemoButton = new MirButton();
        MemoButton->setIndex(560);
        MemoButton->setHoverIndex(561);
        MemoButton->setPressedIndex(562);
        MemoButton->setLibrary(Libraries::Prguse);
        Point tempVar15(116, 241);
        MemoButton->setLocation(&tempVar15);
        MemoButton->setParent(this);
        MemoButton->setSound(SoundList::ButtonA);
        MemoButton->setHint(GameLanguage::FriendMemo);
        MemoButton->Click += [&] (o, e)
        {
            if (SelectedFriend == nullptr)
            {
                return;
            }
    
            GameScene::Scene->MemoDialog->Friend = SelectedFriend;
            GameScene::Scene->MemoDialog->Show();
        };

        EmailButton = new MirButton();
        EmailButton->setIndex(563);
        EmailButton->setHoverIndex(564);
        EmailButton->setPressedIndex(565);
        EmailButton->setLibrary(Libraries::Prguse);
        Point tempVar16(144, 241);
        EmailButton->setLocation(&tempVar16);
        EmailButton->setParent(this);
        EmailButton->setSound(SoundList::ButtonA);
        EmailButton->setHint(GameLanguage::FriendMail);
        EmailButton->Click += [&] (o, e)
        {
            if (SelectedFriend == nullptr)
            {
                return;
            }
    
            GameScene::Scene->MailComposeLetterDialog->ComposeMail(SelectedFriend->Name);
        };

        WhisperButton = new MirButton();
        WhisperButton->setIndex(566);
        WhisperButton->setHoverIndex(567);
        WhisperButton->setPressedIndex(568);
        WhisperButton->setLibrary(Libraries::Prguse);
        Point tempVar17(172, 241);
        WhisperButton->setLocation(&tempVar17);
        WhisperButton->setParent(this);
        WhisperButton->setSound(SoundList::ButtonA);
        WhisperButton->setHint(GameLanguage::FriendWhisper);
        WhisperButton->Click += [&] (o, e)
        {
            if (SelectedFriend == nullptr)
            {
                return;
            }
    
            if (!SelectedFriend->Online)
            {
                GameScene::Scene->ChatDialog->ReceiveChat("Player is not online", ChatType::System);
                return;
            }
    
            GameScene::Scene->ChatDialog->ChatTextBox->SetFocus();
            GameScene::Scene->ChatDialog->ChatTextBox->setText("/" + SelectedFriend->Name + " ");
            GameScene::Scene->ChatDialog->ChatTextBox->setVisible(true);
            GameScene::Scene->ChatDialog->ChatTextBox->TextBox->SelectionLength = 0;
            GameScene::Scene->ChatDialog->ChatTextBox->TextBox->SelectionStart = GameScene::Scene->ChatDialog->ChatTextBox->getText().length();
        };
        #pragma endregion
    }

    void FriendDialog::UpdateDisplay()
    {
        if (!getVisible())
        {
            return;
        }

        if (_blockedTab != _tempBlockedTab)
        {
            _blockedTab = _tempBlockedTab;

            if (_blockedTab)
            {
                FriendLabel->setIndex(164);
                BlacklistLabel->setIndex(166);
            }
            else
            {
                FriendLabel->setIndex(163);
                BlacklistLabel->setIndex(167);
            }
            Update();
            GameScene::Scene->MemoDialog->Hide();
            GameScene::Scene->DisposeMemoLabel();
        }
    }

    void FriendDialog::Update(bool clearSelection)
    {
        if (clearSelection)
        {
            SelectedFriend = nullptr;
        }

        for (int i = 0; i < Rows.size(); i++)
        {
            if (Rows[i] != nullptr)
            {
                Rows[i]->Dispose();
            }

            Rows[i] = nullptr;
        }

        std::vector<ClientFriend*> filteredFriends;

        if (_blockedTab)
        {
            filteredFriends = Friends.Where([&] (std::any e)
            {
                e::Blocked;
            }).ToList();
        }
        else
        {
            filteredFriends = Friends.Where([&] (std::any e)
            {
                return !e::Blocked;
            }).ToList();
        }

        int maxPage = filteredFriends.size() / Rows.size() + 1;
        if (maxPage < 1)
        {
            maxPage = 1;
        }

        PageNumberLabel->setText(std::to_string(Page + 1) + " / " + std::to_string(maxPage));

        int maxIndex = filteredFriends.size() - 1;

        if (StartIndex > maxIndex)
        {
            StartIndex = maxIndex;
        }
        if (StartIndex < 0)
        {
            StartIndex = 0;
        }

        for (int i = 0; i < Rows.size(); i++)
        {
            if (i + StartIndex >= filteredFriends.size())
            {
                break;
            }

            if (Rows[i] != nullptr)
            {
                Rows[i]->Dispose();
            }

            FriendRow *tempVar = new FriendRow();
            tempVar->Friend = filteredFriends[i + StartIndex];
            Point tempVar2((i % 2) * 115 + 16, 55 + ((i) / 2) * 22);
            tempVar->setLocation(&tempVar2);
            tempVar->setParent(this);
            Rows[i] = tempVar;
            Rows[i]->Click += [&] (o, e)
            {
                FriendRow *row = static_cast<FriendRow*>(o);
    
                if (row->Friend != SelectedFriend)
                {
                    SelectedFriend = row->Friend;
                    SelectedIndex = FindSelectedIndex();
                    UpdateRows();
                }
            };

            if (SelectedFriend != nullptr)
            {
                if (SelectedIndex == i)
                {
                    SelectedFriend = Rows[i]->Friend;
                }
            }

            delete tempVar;
        }
    }

    void FriendDialog::UpdateRows()
    {
        if (SelectedFriend == nullptr)
        {
            if (Rows[0] == nullptr)
            {
                return;
            }

            SelectedFriend = Rows[0]->Friend;
        }

        for (int i = 0; i < Rows.size(); i++)
        {
            if (Rows[i] == nullptr)
            {
                continue;
            }

            Rows[i]->Selected = false;

            if (Rows[i]->Friend == SelectedFriend)
            {
                Rows[i]->Selected = true;
            }

            Rows[i]->UpdateInterface();
        }
    }

    int FriendDialog::FindSelectedIndex()
    {
        int selectedIndex = 0;
        if (SelectedFriend != nullptr)
        {
            for (int i = 0; i < Rows.size(); i++)
            {
                if (Rows[i] == nullptr || SelectedFriend != Rows[i]->Friend)
                {
                    continue;
                }

                selectedIndex = i;
            }
        }

        return selectedIndex;
    }

    void FriendDialog::Hide()
    {
        if (!getVisible())
        {
            return;
        }
        setVisible(false);

        GameScene::Scene->MemoDialog->Hide();
    }

    void FriendDialog::Show()
    {
        if (getVisible())
        {
            return;
        }
        setVisible(true);
        UpdateDisplay();
        C::RefreshFriends tempVar();
        Network::Enqueue(&tempVar);
    }

    FriendRow::FriendRow()
    {
        setSound(SoundList::ButtonA);
        Size tempVar(115, 17);
        setSize(&tempVar);

        BeforeDraw += FriendRow_BeforeDraw;

        NameLabel = new MirLabel();
        Point tempVar2(0, 0);
        NameLabel->setLocation(&tempVar2);
        Size tempVar3(115, 17);
        NameLabel->setSize(&tempVar3);
        NameLabel->setBackColour(Color::Empty);
        NameLabel->setDrawFormat(TextFormatFlags::VerticalCenter);
        NameLabel->setParent(this);
        NameLabel->setNotControl(true);

        UpdateInterface();
    }

    void FriendRow::FriendRow_BeforeDraw(std::any sender, EventArgs *e)
    {
        UpdateInterface();
    }

    void FriendRow::UpdateInterface()
    {
        if (Friend == nullptr)
        {
            return;
        }

        NameLabel->setText(Friend->Name);

        if (Friend->Online)
        {
            NameLabel->setForeColour(Color::Green);
        }
        else
        {
            NameLabel->setForeColour(Color::White);
        }

        if (Selected)
        {
            NameLabel->setBackColour(Color::Gray);
        }
        else
        {
            NameLabel->setBackColour(Color::Empty);
        }
    }

    void FriendRow::OnMouseEnter()
    {
        if (Friend == nullptr || Friend->Memo.length() < 1)
        {
            return;
        }

        MirControl::OnMouseEnter();
        GameScene::Scene->CreateMemoLabel(Friend);
    }

    void FriendRow::OnMouseLeave()
    {
        MirControl::OnMouseLeave();
        GameScene::Scene->DisposeMemoLabel();
    }

    void FriendRow::Dispose(bool disposing)
    {
        MirControl::Dispose(disposing);

        Friend = nullptr;
        NameLabel = nullptr;

        Selected = false;
    }

    MemoDialog::MemoDialog()
    {
        setIndex(209);
        setLibrary(Libraries::Title);
        setMovable(true);
        setSort(true);
        setLocation(getCenter());

        MemoTextBox = new MirTextBox();
        MemoTextBox->setForeColour(Color::White);
        MemoTextBox->setParent(this);
        Font tempVar(Settings::FontName, 8.0F);
        MemoTextBox->setFont(&tempVar);
        Point tempVar2(15, 30);
        MemoTextBox->setLocation(&tempVar2);
        Size tempVar3(165, 100);
        MemoTextBox->setSize(&tempVar3);
        MemoTextBox->MultiLine();

        OKButton = new MirButton();
        OKButton->setIndex(382);
        OKButton->setHoverIndex(383);
        OKButton->setPressedIndex(384);
        OKButton->setParent(this);
        OKButton->setLibrary(Libraries::Title);
        OKButton->setSound(SoundList::ButtonA);
        Point tempVar4(30, 133);
        OKButton->setLocation(&tempVar4);
        OKButton->Click += [&] (o, e)
        {
            C::AddMemo *tempVar5 = new C::AddMemo();
            tempVar5->CharacterIndex = Friend->Index;
            tempVar5->Memo = MemoTextBox->getText();
            Network::Enqueue(tempVar5);
            Hide();

//C# TO C++ CONVERTER TODO TASK: A 'delete tempVar5' statement was not added since tempVar5 was passed to a method or constructor. Handle memory management manually.
        };

        CancelButton = new MirButton();
        CancelButton->setIndex(385);
        CancelButton->setHoverIndex(386);
        CancelButton->setPressedIndex(387);
        CancelButton->setParent(this);
        CancelButton->setLibrary(Libraries::Title);
        CancelButton->setSound(SoundList::ButtonA);
        Point tempVar6(115, 133);
        CancelButton->setLocation(&tempVar6);
        CancelButton->Click += [&] (o, e)
        {
            Hide();
        };

        #pragma region Buttons

        CloseButton = new MirButton();
        CloseButton->setHoverIndex(361);
        CloseButton->setIndex(360);
        Point tempVar7(168, 3);
        CloseButton->setLocation(&tempVar7);
        CloseButton->setLibrary(Libraries::Prguse2);
        CloseButton->setParent(this);
        CloseButton->setPressedIndex(362);
        CloseButton->setSound(SoundList::ButtonA);
        CloseButton->Click += [&] (o, e)
        {
            Hide();
        };

        #pragma endregion
    }

    void MemoDialog::Show()
    {
        if (getVisible())
        {
            return;
        }
        setVisible(true);


        if (Friend == nullptr)
        {
            Hide();
            return;
        }

        MemoTextBox->setText(Friend->Memo);
        MemoTextBox->SetFocus();
        MemoTextBox->TextBox->SelectionLength = 0;
        MemoTextBox->TextBox->SelectionStart = MemoTextBox->getText().length();
    }
}
